package com.example.demo.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.example.demo.config.MqttBroker;
import com.example.demo.entity.*;
import com.example.demo.service.*;
import com.example.demo.util.GetMessage;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/rule")
@RequiredArgsConstructor
@Component
public class CodeAssignmentRulesController {
    @Value("${codeSystem.ip}")
    private String ip;
    private final CodeAssignmentRulesService codeAssignmentRulesService;
    private static final ObjectMapper objectMapper = new ObjectMapper();

    private final PurchaseApplyOrderService purchaseApplyOrderService;
    private final CodeHistoryService codeHistoryService;
    private final TrainInfoService trainInfoService;
    private final UserProductinfoService userProductinfoService;
    private final CustomRulesService customRulesService;
    private final PurchaseOrderService purchaseOrderService;

    @CrossOrigin(origins ="*" ,maxAge = 3600)
    @PostMapping("/insert")
    public GetMessage insert (String userId, @RequestBody CodeAssignmentRules codeAssignmentRules) throws JsonProcessingException, MqttException {
        //String userId=token;
        codeAssignmentRules.setCodetype("MA");
        codeAssignmentRules.setUserid(userId);
        boolean bol=codeAssignmentRulesService.save(codeAssignmentRules);
        if(bol){
            Map<String,Object> map=new HashMap<>();
            map.put("type","addRule");
            map.put("appId",codeAssignmentRules.getAppid());
            map.put("trainingId",codeAssignmentRules.getTrainingid());
            String payload = objectMapper.writeValueAsString(map);
            if(codeAssignmentRules.getRuletype().equals("0")){
                MqttBroker.mqttClient.publish("StepInfo/"+codeAssignmentRules.getAppid()+"/"+userId,new MqttMessage(payload.getBytes(StandardCharsets.UTF_8)));
            }
            return new GetMessage("成功","200",codeAssignmentRules);
        }
        return new GetMessage("失败","500",null);
    }
    @CrossOrigin(origins ="*" ,maxAge = 3600)
    @PostMapping("/update")
    public GetMessage update (String userId, @RequestBody CodeAssignmentRules codeAssignmentRules) throws JsonProcessingException, MqttException {
        //String userId=token;
        boolean bol=codeAssignmentRulesService.updateById(codeAssignmentRules);
        if(bol){
            return new GetMessage("成功","200",codeAssignmentRules);
        }
        return new GetMessage("失败","500",null);
    }
    @CrossOrigin(origins ="*" ,maxAge = 3600)
    @GetMapping("/select1")
    public GetMessage select (String userId, String appId,String trainingId,String ruleType){
        //String userId=token;
        List<CodeAssignmentRules> list =codeAssignmentRulesService.select(userId,appId,trainingId,ruleType);
        return new GetMessage("成功","200",list);
    }
    @CrossOrigin(origins ="*" ,maxAge = 3600)
    @GetMapping("/select")
    public GetMessage select1 (String userId, String appId,String trainingId,String ruleType) throws IOException {
        //String userId=token;
        List<CodeAssignmentRules> list =codeAssignmentRulesService.select(userId,appId,null,ruleType);
        if(list.size()==0){
            if(appId.equals("tv")||appId.equals("tvPack")){
                appId="tv";
            }else if(appId.equals("lcd")||appId.equals("lcdPack")){
                appId="lcd";
            }
            Integer isPart=0;
            if(appId.equals("lcd")){
                isPart=1;
            }
            PurchaseOrder purchaseOrder=purchaseOrderService.selectByInfo(userId,trainingId,null,null, String.valueOf(isPart));
            List<UserProductinfo> listUser=userProductinfoService.selectProductInfo(userId,appId,null);
            if(listUser.size()==0){
                //新增型号
                GetMessage mes1=addInfo(userId,trainingId,appId,purchaseOrder.getProductmodel());
                if(!mes1.getMsg().equals("修改型号失败，已注册的型号只能修改分类，无法修改其他数据。")){
                    if(!(mes1.getCode().equals("200"))){

                        return mes1;
                    }
                    //注册
                    GetMessage mes2=register(userId,appId);
                    if(!(mes2.getCode().equals("200"))){
                        return mes2;
                    }
                }else{

                }

            }

            //添加规则
            List<CodeAssignmentRules> codeList=codeAssignmentRulesService.select(userId,appId,null,ruleType);
            Integer id=0;
            if(codeList.size()==0){
                GetMessage mes3=addCustom(userId,trainingId,appId);
                if(!(mes3.getCode().equals("200"))){
                    return mes3;
                }
                GetMessage mes4=addRule(userId,trainingId,appId);
                if(!(mes4.getCode().equals("200"))){

                    return mes4;
                }
                CodeAssignmentRules codeAssignmentRules=(CodeAssignmentRules)mes4.getData();
                id=(Integer) codeAssignmentRules.getId();
            }else{
                id= (Integer) (codeList.get(0).getId());
            }
            List<CodeAssignmentRules> list1 =codeAssignmentRulesService.select(userId,appId,trainingId,ruleType);
//            //赋码
//            GetMessage mes5= getCode(userId,trainingId,appId,id );
//            if(!(mes5.getCode().equals("200"))){
//                return mes5;
//            }

            return new GetMessage("成功","200",list1);
        }
        return new GetMessage("成功","200",list);
    }
    public GetMessage addInfo(String userId,String trainingId, String appId,String model) throws JsonProcessingException, UnsupportedEncodingException {
        Map<String,Object> infoList=Util.getJsonStr(appId,model);
        ObjectMapper mapper = new ObjectMapper();
        String jsonString = mapper.writeValueAsString(infoList);
        TrainInfo trainInfo=trainInfoService.selectByUserId(userId).get(0);
        Map<String,String> headerList=new HashMap<>();
        headerList.put("X-Access-Key",trainInfo.getAccesskey());
        String code="";
        UserProductinfo userProductinfo=new UserProductinfo();
        UserProductinfo u=userProductinfoService.selectProductInfoOne(userId,appId,null);
        if(u==null){
            String res=Util.postUrl(ip+"/api/client/model",headerList,jsonString);
            JSONObject jsonResponse = new JSONObject(res);
            if(jsonResponse.get("code").equals("SUCCESS")){
                JSONObject jsonResponse1 = new JSONObject(jsonResponse.get("data"));
                code=jsonResponse1.get("code").toString();
                userProductinfo.setUserid(userId);
                userProductinfo.setProductinfo("");
                userProductinfo.setAppid(appId);
                userProductinfo.setTrainingid(trainingId);
                userProductinfo.setProductmodel(model);
                userProductinfo.setCategorycode(code);
                userProductinfo.setModelid(jsonResponse1.get("id").toString());
                userProductinfoService.save(userProductinfo);
                return new GetMessage("成功","200",code);
            }else{
                return new GetMessage(jsonResponse.get("message").toString(),"500",code);
            }

        }else{
            return new GetMessage("已新增产品"+u.getProductmodel(),"500",code);
        }
    }
    public GetMessage register(String userId,String appId) throws IOException {
        UserProductinfo userProductinfo=userProductinfoService.selectProductInfoOne(userId,appId,null);
        Map<String,String> headerList=new HashMap<>();
        TrainInfo trainInfo=trainInfoService.selectByUserId(userId).get(0);
        headerList.put("X-Access-Key",trainInfo.getAccesskey());
        String res=Util.putUrl(ip+"/api/client/model/"+userProductinfo.getModelid()+"/register",headerList);
        JSONObject jsonResponse = new JSONObject(res);
        if(jsonResponse.get("code").equals("SUCCESS")){
            JSONObject jsonResponse1 = new JSONObject(jsonResponse.get("data"));
            String code=jsonResponse1.get("code").toString();

            return new GetMessage("成功","200",code);
        }
        return new GetMessage(jsonResponse.get("message").toString(),"500","");
    }
    public GetMessage addCustom(String userId,String trainingId,String appId) throws JsonProcessingException {
        CustomRules customRules=new CustomRules();
        String name="自定义-产品";
        String rule="[datetime|yyyyMMddHHmmss].[random|4].[number|9999]";
        String ruleDesc="批次号.随机码.序列号";
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("name", name);
        jsonMap.put("rule", rule);
        jsonMap.put("ruleDesc", ruleDesc);

        TrainInfo trainInfo=trainInfoService.selectByUserId(userId).get(0);
        Map<String,String> headerList=new HashMap<>();
        headerList.put("X-Access-Key",trainInfo.getAccesskey());
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(jsonMap);
        String res=Util.postUrl(ip+"/api/client/custom-rule",headerList,jsonString);
        JSONObject jsonResponse = new JSONObject(res);
        if(jsonResponse.get("code").equals("SUCCESS")){
            JSONObject jsonResponse1 = new JSONObject(jsonResponse.get("data"));
            customRules.setRuleid(jsonResponse1.get("id"));
            customRules.setRulename(name);
            customRules.setRule(rule);
            customRules.setRuledesc(ruleDesc);
            customRules.setUserid(userId);
            customRules.setTrainingid(trainingId);
            customRules.setAppid(appId);
            boolean bol=customRulesService.save(customRules);
            if(bol){
                return new GetMessage("成功","200",customRules);
            }
        }

        return new GetMessage("失败","500",null);
    }
    public GetMessage addRule(String userId,String trainingId,String appId) throws JsonProcessingException {
        UserProductinfo userProductinfo=userProductinfoService.selectProductInfoOne(userId,appId,null);
//        CodeAssignmentRules codeAssignmentRules=codeAssignmentRulesService.select(userId,"purchaseOrder",trainingId,"0").get(0);
        CustomRules customRules=customRulesService.select(userId,appId,null).get(0);
        if(customRules==null){
            return new GetMessage("未找到自定义规则","500",null);
        }
        String name="产品-"+appId;

        Map<String, Object> bjsonMap = new HashMap<>();
        bjsonMap.put("name", name);
        bjsonMap.put("modelId", userProductinfo.getModelid());
        bjsonMap.put("customRuleId", customRules.getRuleid());
        String bjsonString = objectMapper.writeValueAsString(bjsonMap);

        TrainInfo trainInfo=trainInfoService.selectByUserId(userId).get(0);
        Map<String,String> headerList=new HashMap<>();
        headerList.put("X-Access-Key",trainInfo.getAccesskey());
        String bres=Util.postUrl(ip+"/api/client/identification-code-rule",headerList,bjsonString);
        JSONObject bjsonResponse = new JSONObject(bres);
        if(!(bjsonResponse.get("code").equals("SUCCESS"))){
            return new GetMessage(bjsonResponse.get("message").toString(),"500",null);
        }

        JSONObject bdata = new JSONObject(bjsonResponse.get("data"));
        CodeAssignmentRules codeAssignmentRules=new CodeAssignmentRules();
        codeAssignmentRules.setRulename(name);
        codeAssignmentRules.setCodingid(customRules.getRuleid());
        codeAssignmentRules.setRuletype("0");
        codeAssignmentRules.setAppid(appId);
        codeAssignmentRules.setTrainingid(trainingId);
        codeAssignmentRules.setUserid(userId);
        codeAssignmentRules.setRuleid(bdata.get("id").toString());
        codeAssignmentRules.setCodetype("MA");
        codeAssignmentRules.setUserid(userId);
        boolean bol=codeAssignmentRulesService.save(codeAssignmentRules);
        codeAssignmentRules.setRuletype("1");
        boolean bol1=codeAssignmentRulesService.save(codeAssignmentRules);
        if(bol1){
            return new GetMessage("成功","200",codeAssignmentRules);
        }
        return new GetMessage("失败","500",null);
    }


    @CrossOrigin(origins ="*" ,maxAge = 3600)
    @GetMapping("/delete")
    public GetMessage delete (String userId,Integer id){
        Integer bol =codeAssignmentRulesService.deleteById(id);
        return new GetMessage("成功","200",bol);
    }
}
